package mq

import (
	"encoding/json"
	"github.com/streadway/amqp"
)

type RabbitConf struct {
	Dsn string
	Exchange string
	Queue string
}

type RabbitMQ struct {
	channel *amqp.Channel
	Name string
	exchange string
}

func New(conf RabbitConf) *RabbitMQ {
	conn,err := amqp.Dial(conf.Dsn)
	if err != nil {
		panic(err)
	}

	channle,err := conn.Channel()
	if err != nil {
		panic(err)
	}

	err = channle.ExchangeDeclare(
		conf.Exchange,
		"",
		false,
		true,
		false,
		false,
		nil)
	if err != nil {
		panic(err)
	}

	queue,err := channle.QueueDeclare(
		conf.Queue,
		false,
		true,
		false,
		false,
		nil)
	if err != nil {
		panic(err)
	}

	err = channle.QueueBind(
		queue.Name,
		"",
		conf.Exchange,
		false,
		nil)
	if err != nil {
		panic(err)
	}


	mq := &RabbitMQ{
		channel:channle,
		Name:queue.Name,
		exchange:conf.Exchange,
	}

	return mq
}

func (mq *RabbitMQ) Bind()  {
	err := mq.channel.QueueBind(
		mq.Name,
		"",
		mq.exchange,
		false,
		nil)
	if err != nil {
		panic(err)
	}
}

func (mq *RabbitMQ) Send(queue string, body interface{})  {
	content,err := json.Marshal(body)
	if err != nil {
		panic(err)
	}

	err = mq.channel.Publish(mq.exchange,queue,false,false,
		amqp.Publishing{
			ReplyTo:mq.Name,
			Body:[]byte(content),
		})
	if err != nil {
		panic(err)
	}
}

func (mq *RabbitMQ) Publish(exchange string, body interface{})  {
	content,err := json.Marshal(body)
	if err != nil {
		panic(err)
	}

	err = mq.channel.Publish(exchange,
		"",
		false,
		false,
		amqp.Publishing{
			ReplyTo:mq.Name,
			Body:[]byte(content),
		})
	if err != nil {
		panic(err)
	}
}

func (mq *RabbitMQ) Consume() <- chan amqp.Delivery{
	msgs,err := mq.channel.Consume(
		mq.Name,
		"",
		true,
		false,
		false,
		false,
		nil)
	if err != nil {
		panic(err)
	}
	return msgs
}

func (mq *RabbitMQ) Close()  {
	mq.channel.Close()
}
